package org.jeecg.modules.yc.netty.handlers;

import com.baomidou.mybatisplus.core.conditions.query.QueryWrapper;
import io.netty.buffer.ByteBuf;
import io.netty.channel.ChannelHandler;
import io.netty.channel.ChannelHandlerContext;
import io.netty.channel.ChannelInboundHandlerAdapter;
import org.jeecg.modules.yc.util.SMS4Util;
import org.jeecg.modules.yc.util.TransformationTool;
import org.jeecg.modules.yc.web.entity.DeviceReport;
import org.jeecg.modules.yc.web.entity.Terminal;
import org.jeecg.modules.yc.web.entity.PdDevice;
import org.jeecg.modules.yc.web.service.IDeviceReportService;
import org.jeecg.modules.yc.web.service.ITerminalService;
import org.jeecg.modules.yc.web.service.IPdDeviceService;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Component;

import java.util.Arrays;
import java.util.Date;

@Component
@ChannelHandler.Sharable
public class CSHandler extends ChannelInboundHandlerAdapter {

    @Autowired
    private ITerminalService terminalService;
    @Autowired
    private IDeviceReportService deviceReportService;
    @Autowired
    private IPdDeviceService ycPdDeviceService;

    @Override
    public void channelRead(ChannelHandlerContext ctx, Object msg) {
        ByteBuf buf = (ByteBuf) msg;
        try {
            byte[] data = new byte[buf.readableBytes()];
            buf.readBytes(data);
            String received = new String(data);
            System.out.println("Server received: " + received);
            data = SMS4Util.decrypt(data);
            assert data != null;
            if(data[0] == 0x0a && data[1] == 0x0b && data.length == 256){
                byte[] pdData = Arrays.copyOfRange(data,6,246);
                String terminalNo = TransformationTool.bytesHexString(Arrays.copyOfRange(data,2,4));
                String deviceNo = TransformationTool.bytesHexString(Arrays.copyOfRange(data,4,6));
                Terminal terminal = terminalService.getOne(new QueryWrapper<Terminal>().eq("no",terminalNo));
                if(terminal == null){
                    return;
                }else{
                    terminalService.updateById(Terminal.builder().id(terminal.getId()).lastConnectTime(new Date()).build());
                }
                PdDevice ycPdDevice = ycPdDeviceService.getOne(new QueryWrapper<PdDevice>().eq("no",deviceNo));
                if(ycPdDevice == null){
                    return;
                }
                System.out.println("terminal_no:"+terminalNo);
                System.out.println("device_no:"+deviceNo);
                int dBMax = 0;
                int dBMin = 0;
                int temperatureMax = 0;
                int temperatureMin = 0;
                for(int i = 0 ; i < 59 ; i++){
                    int temperatureOne = pdData[i*4] << 8 | pdData[i*4+1];
                    int dBOne = pdData[i*4+2] << 8 | pdData[i*4+3];
                    int temperatureTow = pdData[i*4+4] << 8 | pdData[i*4+5];
                    int dBTow = pdData[i*4+6] << 8 | pdData[i*4+7];
                    if(temperatureOne > temperatureTow){
                        temperatureMax = temperatureOne;
                        temperatureMin = temperatureTow;
                    }else {
                        temperatureMax = temperatureTow;
                        temperatureMin = temperatureOne;
                    }
                    if(dBOne > dBTow){
                        dBMax = dBOne;
                        dBMin = dBTow;
                    }else {
                        dBMax = dBTow;
                        dBMin = dBOne;
                    }
                }
                ycPdDeviceService.updateById(PdDevice.builder().id(ycPdDevice.getId()).communicationTime(new Date()).temperature(String.valueOf(data[236] << 8 | data[237]))
                        .pdStrength(String.valueOf(data[238] << 8 | data[239])).build());
                deviceReportService.save(DeviceReport.builder().deviceNo(deviceNo).deviceName(ycPdDevice.getName())
                        .pdMax(String.valueOf(dBMax)).pdMin(String.valueOf(dBMin))
                        .terminalName(terminal.getName()).terminalNo(terminalNo)
                        .temperatureMax(String.valueOf(temperatureMax)).temperatureMin(String.valueOf(temperatureMin))
                        .metadata(TransformationTool.bytesHexString(pdData)).build());
            }
        } finally {
            buf.release();
        }
    }

    @Override
    public void exceptionCaught(ChannelHandlerContext ctx, Throwable cause) {
        cause.printStackTrace();
        ctx.close();
    }
}
